namespace MoreLinq.Test;

using System;
using NUnit.Framework.Constraints;

static class Throws
{
    public static ThrowsNothingConstraint Nothing => NUnit.Framework.Throws.Nothing;
    public static ExactTypeConstraint InvalidOperationException => NUnit.Framework.Throws.InvalidOperationException;
    public static ExactTypeConstraint ObjectDisposedException => TypeOf<ObjectDisposedException>();
    public static ExactTypeConstraint BreakException => TypeOf<BreakException>();

    public static InstanceOfTypeConstraint InstanceOf<T>()
        where T : Exception =>
        NUnit.Framework.Throws.InstanceOf<T>();

    public static ExactTypeConstraint TypeOf<T>()
        where T : Exception =>
        NUnit.Framework.Throws.TypeOf<T>();

    public static EqualStringConstraint ArgumentException(string expectedParamName) =>
        NUnit.Framework.Throws.ArgumentException.With.ParamName(expectedParamName);

    public static EqualStringConstraint ArgumentNullException(string expectedParamName) =>
        NUnit.Framework.Throws.ArgumentNullException.With.ParamName(expectedParamName);

    public static ExactTypeConstraint ArgumentOutOfRangeException() =>
        TypeOf<ArgumentOutOfRangeException>();

    public static EqualStringConstraint ArgumentOutOfRangeException(string expectedParamName) =>
        ArgumentOutOfRangeException().With.ParamName(expectedParamName);

    public static EqualStringConstraint ParamName(this ConstraintExpression constraint, string expectedParamName) =>
        constraint.ParamName().EqualTo(expectedParamName);

    static ResolvableConstraintExpression ParamName(this ConstraintExpression constraint) =>
        constraint.Property(nameof(System.ArgumentException.ParamName));
}
